package com.redside.model;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

import com.redside.model.lookup.BusinessCatLkp;

/**
 * @author PCHAPMAN
 * 
 */
@Entity
@Table(name = "business")
public class Business extends BaseObject implements java.io.Serializable {

    private static final long serialVersionUID = -4375030307941697786L;
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "business_id")
    private Long id;
    
    @ManyToOne
    @JoinColumn(name = "bus_cat_id", nullable = false)
    private BusinessCatLkp businessCatLkp;
    
    @Column(name="active",nullable=false)
    private boolean active;
    
    @Column(name = "business_name", nullable = false, length = 50)
    private String businessName;

    @Embedded
    private Address address = new Address();
    
    @Column(name = "business_phone", length = 14)
    private String businessPhone;
    
    @Column(name = "business_phone_ext", length = 6)
    private String businessPhoneExt;
    
    @Column(name = "contact_name", length = 50)
    private String contactName;
    
    @Column(name = "contact_title", length = 50)
    private String contactTitle;
    
    @Column(name = "contact_email", unique=true, length = 50)
    private String contactEmail;
    
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "note_id")
    private Set<Note> notes = new HashSet<Note>(0);

    @ManyToOne
    @JoinColumn(name = "parent_id")
    private ParentBusiness parentBusiness;
    
    @Column(name="parent_contact",nullable=false)
    private boolean parentAsContact;
    
    @Column(name="in_violation",nullable=false)
    private boolean inViolation;
    
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "business_id")
    private List<Complaint> complaints = new ArrayList<Complaint>(0);

    public Business() {
    }

    // for testing
    public Business(Long id, BusinessCatLkp businessCatLkp, boolean active,
            String countyId, String stateId, String businessName,
            boolean parentAsContact) {
        this.id = id;
        this.businessCatLkp = businessCatLkp;
        this.active = active;
        this.address.setCountyId(countyId);
        this.address.setStateId(stateId);
        this.businessName = businessName;
        this.parentAsContact=parentAsContact;
    }

    public Business(BusinessCatLkp businessCatLkp, boolean active, String countyId,
            String stateId, String businessName, String address1,
            String businessAddress2, String businessCity, String businessZip,
            String businessZipExt, String businessPhone, String contactName,
            String contactEmail, ParentBusiness parentBusiness, List<Complaint> complaints) {
        this.businessCatLkp = businessCatLkp;
        this.address.setCountyId(countyId);
        this.active = active;
        this.address.setStateId(stateId);
        this.businessName = businessName;
        this.address.setAddress1(address1);
        this.address.setAddress2(businessAddress2);
        this.address.setCity(businessCity);
        this.address.setPostalCode(businessZip);
        this.address.setPostalCodeExt(businessZipExt);
        this.businessPhone = businessPhone;
        this.contactName = contactName;
        this.contactEmail = contactEmail;
        this.parentBusiness = parentBusiness;
        this.complaints = complaints;
    }

    /**
     * Used by BusinessAssociatorFormController
     * 
     * @param businessCatLkp
     * @param countyLkp
     * @param stateLkp
     * @param businessName
     * @param businessOwner
     * @param businessOwnerTitle
     * @param businessOwnerPhone
     * @param businessOwnerEmail
     * @param address1
     * @param businessAddress2
     * @param businessCity
     * @param businessZip
     * @param businessState
     * @param businessPhone
     * @param contactName
     * @param contactTitle
     * @param contactEmail
     */
    public Business(BusinessCatLkp businessCatLkp, boolean active, String countyId,
            String stateId, String businessName, String address1, String businessAddress2,
            String businessCity, String businessZip, String businessZipExt,
            String businessState, String businessPhone, String businessPhoneExt,
            String contactName, String contactTitle, String contactEmail) {
        this.businessCatLkp = businessCatLkp;
        this.active = active;
        this.address.setCountyId(countyId);
        this.address.setStateId(stateId);
        this.businessName = businessName;
        this.address.setAddress1(address1);
        this.address.setAddress2(businessAddress2);
        this.address.setCity(businessCity);
        this.address.setPostalCode(businessZip);
        this.address.setPostalCodeExt(businessZipExt);
        this.businessPhone = businessPhone;
        this.businessPhoneExt = businessPhoneExt;
        this.contactName = contactName;
        this.contactTitle = contactTitle;
        this.contactEmail = contactEmail;
    }

    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @return the businessCatLkp
     */
    public BusinessCatLkp getBusinessCatLkp() {
        return businessCatLkp;
    }

    /**
     * @param businessCatLkp the businessCatLkp to set
     */
    public void setBusinessCatLkp(BusinessCatLkp businessCatLkp) {
        this.businessCatLkp = businessCatLkp;
    }

    /**
     * @return the active
     */
    public boolean isActive() {
        return active;
    }

    /**
     * @param active the active to set
     */
    public void setActive(boolean active) {
        this.active = active;
    }

    /**
     * @return the businessName
     */
    public String getBusinessName() {
        return businessName;
    }

    /**
     * @param businessName the businessName to set
     */
    public void setBusinessName(String businessName) {
        this.businessName = businessName;
    }

    /**
	 * @return the address
	 */
	public Address getAddress() {
		return address;
	}

	/**
	 * @param address the address to set
	 */
	public void setAddress(Address address) {
		this.address = address;
	}

	/**
     * @return the businessPhone
     */
    public String getBusinessPhone() {
        return businessPhone;
    }

    /**
     * @param businessPhone the businessPhone to set
     */
    public void setBusinessPhone(String businessPhone) {
        this.businessPhone = businessPhone;
    }

    /**
     * @return the businessPhoneExt
     */
    public String getBusinessPhoneExt() {
        return businessPhoneExt;
    }

    /**
     * @param businessPhoneExt the businessPhoneExt to set
     */
    public void setBusinessPhoneExt(String businessPhoneExt) {
        this.businessPhoneExt = businessPhoneExt;
    }

    /**
     * @return the contactName
     */
    public String getContactName() {
        return contactName;
    }

    /**
     * @param contactName the contactName to set
     */
    public void setContactName(String contactName) {
        this.contactName = contactName;
    }

    /**
     * @return the contactTitle
     */
    public String getContactTitle() {
        return contactTitle;
    }

    /**
     * @param contactTitle the contactTitle to set
     */
    public void setContactTitle(String contactTitle) {
        this.contactTitle = contactTitle;
    }

    /**
     * @return the contactEmail
     */
    public String getContactEmail() {
        return contactEmail;
    }

    /**
     * @param contactEmail the contactEmail to set
     */
    public void setContactEmail(String contactEmail) {
        this.contactEmail = contactEmail;
    }

    /**
     * @return the notes
     */
    public Set<Note> getNotes() {
        return notes;
    }

    /**
     * @param notes the notes to set
     */
    public void setNotes(Set<Note> notes) {
        this.notes = notes;
    }

    /**
     * @return the parentBusiness
     */
    public ParentBusiness getParentBusiness() {
        return parentBusiness;
    }

    /**
     * @param parentBusiness the parentBusiness to set
     */
    public void setParentBusiness(ParentBusiness parentBusiness) {
        this.parentBusiness = parentBusiness;
    }

    /**
     * @return the parentAsContact
     */
    public boolean isParentAsContact() {
        return parentAsContact;
    }

    /**
     * @param parentAsContact the parentAsContact to set
     */
    public void setParentAsContact(boolean parentAsContact) {
        this.parentAsContact = parentAsContact;
    }

    /**
     * @return the inViolation
     */
    public boolean isInViolation() {
        return inViolation;
    }

    /**
     * @param inViolation the inViolation to set
     */
    public void setInViolation(boolean inViolation) {
        this.inViolation = inViolation;
    }

    /**
     * @return the complaints
     */
    public List<Complaint> getComplaints() {
        return complaints;
    }

    /**
     * @param complaints the complaints to set
     */
    public void setComplaints(List<Complaint> complaints) {
        this.complaints = complaints;
    }
    
    public void addComplaint(Complaint complaint) {
        List<Complaint> complaints = this.getComplaints();
        if (complaints == null) {
            complaints = new ArrayList<Complaint>();
        }
        complaints.add(complaint);
        this.setComplaints(complaints);
    }

	/**
	 * @see java.lang.Object#equals(Object)
	 */
	public boolean equals(Object object) {
		if (!(object instanceof Business)) {
			return false;
		}
		Business rhs = (Business) object;
		return new EqualsBuilder().append(
				this.businessName, rhs.businessName).append(this.businessPhone,
				rhs.businessPhone).append(this.parentBusiness,
				rhs.parentBusiness).append(this.contactEmail, rhs.contactEmail)
				.append(this.contactTitle, rhs.contactTitle).append(
						this.complaints, rhs.complaints).append(this.inViolation,
						rhs.inViolation).append(this.businessCatLkp,
						rhs.businessCatLkp).append(this.address, rhs.address)
				.append(this.contactName, rhs.contactName).append(
						this.businessPhoneExt, rhs.businessPhoneExt).append(
						this.active, rhs.active).append(this.notes, rhs.notes)
				.append(this.parentAsContact, rhs.parentAsContact).isEquals();
	}

	/**
	 * @see java.lang.Object#hashCode()
	 */
	public int hashCode() {
		return new HashCodeBuilder(1716908799, -1046988051).append(this.businessName)
				.append(this.businessPhone).append(this.parentBusiness).append(
				this.contactEmail).append(this.contactTitle).append(
				this.complaints).append(this.inViolation)
				.append(this.businessCatLkp).append(this.address).append(
						this.contactName).append(this.businessPhoneExt).append(
						this.active).append(this.notes).append(
						this.parentAsContact).toHashCode();
	}

	/**
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		return new ToStringBuilder(this)
				.append("contactName", this.contactName).append("contactTitle",
						this.contactTitle)
				.append("complaints", this.complaints).append("contactEmail",
						this.contactEmail).append("parentAsContact",
						this.parentAsContact).append("active", this.active)
				.append("businessCatLkp", this.businessCatLkp).append(
						"businessName", this.businessName).append(
						"inViolation", this.inViolation).append(
						"businessPhone", this.businessPhone).append("notes",
						this.notes).append("businessPhoneExt",
						this.businessPhoneExt).append("id", this.id).append(
						"address", this.address).append("parentBusiness",
						this.parentBusiness).toString();
	}

 
}
